//
//  SWNetworkMonitor.swift
//  ThirdPartComponentTest
//
//  Created by linhan on 16/6/3.
//  Copyright © 2016年 me. All rights reserved.
//

import Foundation

private let _monitor = SWNetworkMonitor()

enum SWNetworkStatus:String
{
    case unknow
    case notReachable
    case WiFi
    case cellular
    
    var notificationName:Notification.Name
    {
        switch self {
        case .unknow: return .SWNetworkMonitorReachableWiFi
        case .WiFi: return .SWNetworkMonitorReachableWiFi
        case .cellular: return .SWNetworkMonitorReachableCellular
        case .notReachable: return .SWNetworkMonitorNotReachable
        }
    }
    
}

extension Notification.Name
{
    public static let SWNetworkMonitorReachableWiFi = Notification.Name(rawValue: "ReachableWiFi")
    public static let SWNetworkMonitorReachableCellular = Notification.Name(rawValue: "ReachableCellular")
    public static let SWNetworkMonitorNotReachable = Notification.Name(rawValue: "NotReachable")
}

class SWNetworkMonitor: NSObject
{
    private var _setuped:Bool = false
    private var _reachability:Reachability?
    
    var status:SWNetworkStatus{
        return _status
    }
    
    private var _status:SWNetworkStatus = .unknow {
        didSet{
            if _status != oldValue && oldValue != .unknow {
                NotificationCenter.default.post(name: _status.notificationName, object: nil)
            }
        }
    }
    
    class func sharedMonitor() -> SWNetworkMonitor
    {
        return _monitor
    }
    
    func setup(hostName: String?)
    {
        if _setuped
        {
            return
        }
        _setuped = true
        
        _reachability = hostName == nil ? Reachability() : Reachability(hostname: hostName!)
        _reachability?.whenReachable = {[weak self] reachability in
            self?._status = reachability.isReachableViaWiFi ? .WiFi : .cellular
        }
        _reachability?.whenUnreachable = {[weak self] reachability in
            self?._status = .notReachable
        }
        
        startNotifier()
    }
    
    func startNotifier()
    {
        do {
            try _reachability?.startNotifier()
        } catch {
            print("Unable to start notifier")
        }
    }
    
    func stopNotifier()
    {
        _reachability?.stopNotifier()
    }
    
    
}
